home *** CD-ROM | disk | FTP | other *** search
/ Hottest 6 / Hottest 6 (1996)(PDSoft)[!].iso / software / rendering / pov / povray40 / targa.c < prev   
C/C++ Source or Header  |  1978-11-24  |  8KB  |  289 lines

  1. /****************************************************************************
  2. *                targa.c
  3. *
  4. *  This module contains the code to read and write the Targa output file
  5. *  format.
  6. *
  7. *  from Persistence of Vision Raytracer
  8. *  Copyright 1992 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  Copying, distribution and legal info is in the file povlegal.doc which
  11. *  should be distributed with this file. If povlegal.doc is not available
  12. *  or for more info please contact:
  13. *
  14. *       Drew Wells [POV-Team Leader]
  15. *       CIS: 73767,1244  Internet: 73767.1244@compuserve.com
  16. *       Phone: (213) 254-4041
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "povproto.h"
  26.  
  27. int Targa_Line_Number = 0;
  28.  
  29. extern int First_Line;
  30.  
  31. FILE_HANDLE *Get_Targa_File_Handle()
  32. {
  33.    FILE_HANDLE *handle;
  34.  
  35.    if ((handle = (FILE_HANDLE *) malloc(sizeof(FILE_HANDLE))) == NULL) {
  36.       fprintf (stderr, "Cannot allocate memory for output file handle\n");
  37.       return(NULL);
  38.    }
  39.  
  40.    handle->Default_File_Name_p = Default_Targa_File_Name;
  41.    handle->Open_File_p = Open_Targa_File;
  42.    handle->Write_Line_p = Write_Targa_Line;
  43.    handle->Read_Line_p = Read_Targa_Line;
  44.    handle->Read_Image_p = Read_Targa_Image;
  45.    handle->Close_File_p = Close_Targa_File;
  46.    handle->file = NULL;
  47.    handle->buffer_size = 0;
  48.    handle->buffer = NULL;
  49.    return (handle);
  50. }
  51.  
  52. char *Default_Targa_File_Name()
  53. {
  54.    return ("data.tga");
  55. }
  56.  
  57. int Open_Targa_File (handle, name, width, height, buffer_size, mode)
  58. FILE_HANDLE *handle;
  59. char *name;
  60. int *width;
  61. int *height;
  62. int buffer_size;
  63. int mode;
  64. {
  65.    int data1, data2, i;
  66.  
  67.    handle->mode = mode;
  68.    handle->filename = name;
  69.  
  70.    switch (mode) {
  71.    case READ_MODE:
  72.       if ((handle->file = fopen (name, READ_FILE_STRING)) == NULL)
  73.          return(0);
  74.  
  75.       if (buffer_size != 0) {
  76.          if ((handle->buffer = malloc (buffer_size)) == NULL)
  77.             return(0);
  78.  
  79.          setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
  80.       }
  81.  
  82.       for (i = 0 ; i < 12 ; i++)
  83.          if (getc(handle->file) == EOF)
  84.             return(0);
  85.  
  86.       if (((data1 = getc(handle->file)) == EOF)
  87.          || ((data2 = getc(handle->file)) == EOF))
  88.          return(0);
  89.  
  90.       *width  = data2 * 256 + data1;
  91.  
  92.       if (((data1 = getc(handle->file)) == EOF)
  93.          || ((data2 = getc(handle->file)) == EOF))
  94.          return(0);
  95.  
  96.       for (i = 0 ; i < 2 ; i++)
  97.          if (getc(handle->file) == EOF)
  98.             return(0);
  99.  
  100.       *height = data2 * 256 + data1;
  101.       handle->width = *width;
  102.       handle->height = *height;
  103.       handle->buffer_size = buffer_size;
  104.       break;
  105.  
  106.    case WRITE_MODE:
  107.       if ((handle->file = fopen (name, WRITE_FILE_STRING)) == NULL)
  108.          return(0);
  109.  
  110.       if (buffer_size != 0) {
  111.          if ((handle->buffer = malloc (buffer_size)) == NULL)
  112.             return(0);
  113.  
  114.          setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
  115.       }
  116.  
  117.       for (i = 0; i < 10; i++)       /* 00, 00, 02, then 7 00's... */
  118.          if (i == 2)
  119.             putc(i, handle->file);
  120.          else
  121.             putc(0, handle->file);
  122.  
  123.       putc((First_Line & 0xFF), handle->file); /* y origin set to "First_Line" */
  124.  
  125.       putc(((First_Line >> 8) & 0xFF), handle->file);
  126.  
  127.       putc((*width & 0xFF), handle->file);  /* write width and height */
  128.       putc(((*width >> 8) & 0xFF), handle->file);
  129.       putc((*height & 0xFF), handle->file);
  130.       putc(((*height >> 8) & 0xFF), handle->file);
  131.       putc(24, handle->file);                /* 24 bits/pixel (16 million col */
  132.       putc(32, handle->file);                /* Bitmask, pertinent bit: top-d */
  133.  
  134.       handle->width = *width;
  135.       handle->height = *height;
  136.       handle->buffer_size = buffer_size;
  137.  
  138.       break;
  139.  
  140.    case APPEND_MODE:
  141.       if ((handle->file = fopen (name, APPEND_FILE_STRING)) == NULL)
  142.          return(0);
  143.  
  144.       if (buffer_size != 0) {
  145.          if ((handle->buffer = malloc (buffer_size)) == NULL)
  146.             return(0);
  147.  
  148.          setvbuf (handle->file, handle->buffer, _IOFBF, buffer_size);
  149.       }
  150.  
  151.       break;
  152.    }
  153.  
  154.    return(1);
  155. }
  156.  
  157. void Write_Targa_Line (handle, line_data, line_number)
  158. FILE_HANDLE *handle;
  159. COLOUR *line_data;
  160. int line_number;
  161. {
  162.    register int x;
  163.  
  164.    for (x = 0; x < handle->width; x++) {
  165.       putc((int) floor (line_data[x].Blue * 255.0), handle->file);
  166.       putc((int) floor (line_data[x].Green * 255.0), handle->file);
  167.       putc((int) floor (line_data[x].Red * 255.0), handle->file);
  168.    }
  169.  
  170.    if (handle->buffer_size == 0) {
  171.       fflush(handle->file);                       /* close and reopen file for */
  172.       handle->file = freopen(handle->filename, APPEND_FILE_STRING,
  173.          handle->file);                /* integrity in case we crash*/
  174.    }
  175. }
  176.  
  177. int Read_Targa_Line (handle, line_data, line_number)
  178. FILE_HANDLE *handle;
  179. COLOUR *line_data;
  180. int *line_number;
  181. {
  182.    int x, data;
  183.  
  184.    for (x = 0; x < handle->width; x++) {
  185.  
  186.       /* Read the BLUE data byte.  If EOF is reached on the first character read,
  187.       then this line hasn't been rendered yet.  Return 0.  If an EOF occurs
  188.       somewhere within the line, this is an error - return -1. */
  189.  
  190.       if ((data = getc(handle->file)) == EOF)
  191.          if (x == 0)
  192.             return (0);
  193.          else
  194.             return (-1);
  195.  
  196.       line_data[x].Blue = (DBL) data / 255.0;
  197.  
  198.       /* Read the GREEN data byte. */
  199.       if ((data = getc(handle->file)) == EOF)
  200.          return (-1);
  201.       line_data[x].Green = (DBL) data / 255.0;
  202.  
  203.  
  204.       /* Read the RED data byte. */
  205.       if ((data = getc(handle->file)) == EOF)
  206.          return (-1);
  207.       line_data[x].Red = (DBL) data / 255.0;
  208.    }
  209.  
  210.    *line_number = Targa_Line_Number++;
  211.    return(1);
  212. }
  213.  
  214. void Close_Targa_File (handle)
  215. FILE_HANDLE *handle;
  216. {
  217.    if(handle->file)
  218.       fclose (handle->file);
  219.    if (handle->buffer)
  220.       free (handle->buffer);
  221. }
  222.  
  223. int Read_Targa_Int_Line(handle, line_data)
  224. FILE_HANDLE *handle;
  225. IMAGE_LINE *line_data;
  226. {
  227.    int x, data;
  228.  
  229.    if (((line_data->red = (unsigned char *) malloc(handle->width))==NULL) ||
  230.       ((line_data->green = (unsigned char *) malloc(handle->width))==NULL) ||
  231.       ((line_data->blue = (unsigned char *) malloc(handle->width))==NULL)) {
  232.       fprintf(stderr, "Cannot allocate memory for picture: %s\n",
  233.          handle->filename);
  234.       close_all();
  235.       exit(1);
  236.    }
  237.  
  238.    for (x = 0; x < handle->width; x++) {
  239.       if ((data = getc(handle->file)) == EOF)
  240.          if (x == 0) return (0);
  241.          else return (-1);
  242.       line_data->blue[x] = data;
  243.       if ((data = getc(handle->file)) == EOF) return (-1);
  244.       line_data->green[x] = data;
  245.       if ((data = getc(handle->file)) == EOF) return (-1);
  246.       line_data->red[x] = data;
  247.    }
  248.    return(1);
  249. }
  250.  
  251. void
  252. Read_Targa_Image(Image, name)
  253. IMAGE *Image;
  254. char *name;
  255. {
  256.    int row;
  257.    FILE_HANDLE handle;
  258.  
  259.    if ((handle.file = Locate_File(name, READ_FILE_STRING)) == NULL) {
  260.       fprintf (stderr, "Cannot open Targa file %s\n", name);
  261.       close_all();
  262.       exit(1);
  263.    }
  264.  
  265.    Open_Targa_File(&handle, name, &Image->iwidth, &Image->iheight,
  266.       0, READ_MODE);
  267.  
  268.    handle.width  = Image->iwidth;
  269.    handle.height = Image->iheight;
  270.    Image->width = (DBL)Image->iwidth;
  271.    Image->height = (DBL)Image->iheight;
  272.    Image->Colour_Map_Size = 0;
  273.    Image->Colour_Map = NULL;
  274.  
  275.    if ((Image->data.rgb_lines = (struct Image_Line *)
  276.       malloc(Image->iheight * sizeof (struct Image_Line))) == NULL) {
  277.       fprintf (stderr, "Cannot allocate memory for picture: %s\n", name);
  278.       exit(1);
  279.    }
  280.  
  281.    for (row=0;
  282.               row<Image->iheight &&
  283.               Read_Targa_Int_Line(&handle, &Image->data.rgb_lines[row]);
  284.               row++) {
  285.    }
  286.    fclose(handle.file);
  287. }
  288.  
  289.